package br.com.iswe.gerador.velocity.gerador;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import br.com.iswe.gerador.velocity.info.InfoEntidadeImpl;
import br.com.iswe.gerador.velocity.info.InfoGerador;

public class GeradorBO extends GeradorBase {

	private static final String FULL_PACKAGE_DAO = "fullPackageDAO";
	private static final String BOABSTRACT_JAVA = "BOAbstract.java";
    private static final String BO_ABSTRACT_VM = "BO-ABSTRACT.vm";
    private static final String GERADOR_BO_PASTA_SAIDA = "gerador.bo.pasta.saida";
	private static final String BO_IMPL_VM = "BO-IMPL.vm";
	private static final String BO_INTERFACE_VM = "BO-INTERFACE.vm";
	private static final String BO_IMPL_JAVA = "BOImpl.java";
	private static final String BO_JAVA = "BO.java";
	private static final String PACOTE_BO = "PacoteBO";
	public static final String GERADOR_BO_PACKAGE_TO = "gerador.bo.package.to";
	public static final String GERADOR_BO_PACKAGE_FROM = "gerador.bo.package.from";
	public static final String NOME_GERADOR = "geradorBO";

	private InfoGerador infoGerador;

	public void gerarCodigo(InfoEntidadeImpl info) throws Exception {
		Template template = null;
		Writer wrt = null;
		String arquivoSaida = null;
		
        //Obtem o pacote para objetos abstratos
        String pacoteAbstrato = infoGerador.getPacoteAbstratos();
        
		// Primeiro Passo : Cria o contexto com as informa��es necess�rias para
		// criar a classe de BO.
		VelocityContext ctx = buildContext(this.infoGerador);
		// Obt�m o Pakage do componente :
		String packageBO = info.getReplacePackage(GERADOR_BO_PACKAGE_FROM,
				GERADOR_BO_PACKAGE_TO);
		ctx.put(PACOTE_BO, packageBO);
		// Adiciona a info da entidade
		ctx.put(InfoEntidadeImpl.NOME_INFO, info);
		
		// Obt�m o package do DAO que � necess�rio na classe BO
		String fullPackageDAO = info.getReplacePackage(GeradorDAO.GERADOR_DAO_PACKAGE_FROM, GeradorDAO.GERADOR_DAO_PACKAGE_TO);
		info.setPropriedade(FULL_PACKAGE_DAO, fullPackageDAO);

		// Segundo Passo : Obt�m o diret�rio onde ser� gerado o fonte de sa�da.
		String basePath = infoGerador.getPastaBaseSaida() + SEPARADOR
				+ infoGerador.getPropriedade(GERADOR_BO_PASTA_SAIDA);
		File pathSaida = new File(basePath + SEPARADOR
				+ infoGerador.getPathFromPackage(packageBO));
		// Verifica se o path ja existe
		if (!pathSaida.exists()) {
			pathSaida.mkdirs();
		}

        //verifica se existe a pasta de abstratos
        File pastaAbstratos = new File(pathSaida.getAbsolutePath() + SEPARADOR + pacoteAbstrato);
        if(!pastaAbstratos.exists()){
            pastaAbstratos.mkdirs();
        }
        
		// Terceiro Passo : Verifica se a classe implementada do BO j� est�
		// criada. Se estiver, aborta a gera��o da classe implementada
		arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + BO_IMPL_JAVA;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
			// Quarto Passo : Obt�m o Template do BO e gera a sa�da.
			// Gerando a classe de implementacao do BO
			template = Velocity.getTemplate(BO_IMPL_VM);
			// Escreve o arquivo de sa�da
			wrt = new FileWriter(arquivoSaida);
			// Gera o documento.
			template.merge(ctx, wrt);
			// Descarrega para o disco.
			wrt.flush();
			wrt.close();
		}

        arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + BO_JAVA;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
            // Quarto Passo : Obt�m o Template do BO e gera a sa�da.
            // Gerando a classe de implementacao do BO
            template = Velocity.getTemplate(BO_INTERFACE_VM);
            // Escreve o arquivo de sa�da
            wrt = new FileWriter(arquivoSaida);
            // Gera o documento.
            template.merge(ctx, wrt);
            // Descarrega para o disco.
            wrt.flush();
            wrt.close();
        }
        
        arquivoSaida = pastaAbstratos.getAbsoluteFile() + SEPARADOR + info.getNomeEntidade1() + BOABSTRACT_JAVA;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
			// Gerando a abstrata do BO
			template = Velocity.getTemplate(BO_ABSTRACT_VM);
			// Escreve o arquivo de sa�da
			wrt = new FileWriter(arquivoSaida);
			// Gera o documento.
			template.merge(ctx, wrt);
			// Descarrega para o disco.
			wrt.flush();
			wrt.close();
        }
	}

	public void inicio(InfoGerador infoGerador) {
		this.infoGerador = infoGerador;
	}

	public void fim() {
		this.infoGerador = null;
	}
}
